<template>
  <div ref="container" class="warehouse-scene">
    <div class="controls-info">
      <p>鼠标左键: 旋转视角</p>
      <p>鼠标滚轮: 缩放</p>
      <p>鼠标右键: 平移</p>
      <p>双击仓库: 进入内部视图</p>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import * as THREE from 'three'

const emit = defineEmits(['warehouse-selected'])
const container = ref(null)

let scene, camera, renderer, raycaster, mouse, controls

// 仓库配置
const warehouseConfigs = [
  { name: "仓库 A", position: { x: -25, z: -15 } },
  { name: "仓库 B", position: { x: 20, z: -15 } },
  { name: "仓库 C", position: { x: -25, z: 15 } },
  { name: "仓库 D", position: { x: 20, z: 15 } }
]

onMounted(async () => {
  await init()
  animate()
})

onUnmounted(() => {
  if (renderer) {
    renderer.dispose()
  }
  if (controls) {
    controls.dispose()
  }
  window.removeEventListener('resize', onWindowResize)
  if (renderer && renderer.domElement) {
    renderer.domElement.removeEventListener('dblclick', onDoubleClick)
  }
})

const init = async () => {
  // 初始化场景
  scene = new THREE.Scene()
  scene.background = new THREE.Color(0x87CEEB)

  // 初始化相机
  camera = new THREE.PerspectiveCamera(
    45,
    container.value.clientWidth / container.value.clientHeight,
    0.1,
    1000
  )
  camera.position.set(0, 30, 40)
  camera.lookAt(0, 0, 0)

  // 初始化渲染器
  renderer = new THREE.WebGLRenderer({ antialias: true })
  renderer.setSize(container.value.clientWidth, container.value.clientHeight)
  renderer.setPixelRatio(window.devicePixelRatio)
  container.value.appendChild(renderer.domElement)

  // 初始化射线检测器和鼠标对象
  raycaster = new THREE.Raycaster()
  mouse = new THREE.Vector2()

  // 添加灯光
  const ambientLight = new THREE.AmbientLight(0xffffff)
  scene.add(ambientLight)

  const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8)
  directionalLight.position.set(1, 1, 1)
  scene.add(directionalLight)

  // 创建灰白色地面
  const groundGeometry = new THREE.PlaneGeometry(100, 100)
  const groundMaterial = new THREE.MeshStandardMaterial({
    color: 0xD3D3D3,
    roughness: 0.8,
    metalness: 0.2
  })
  const ground = new THREE.Mesh(groundGeometry, groundMaterial)
  ground.rotation.x = -Math.PI / 2
  scene.add(ground)

  // 添加网格辅助地面
  const gridHelper = new THREE.GridHelper(100, 20, 0x000000, 0x000000)
  gridHelper.material.opacity = 0.2
  gridHelper.material.transparent = true
  scene.add(gridHelper)

  // 创建仓库
  createWarehouses()

  // 添加轨道控制器
  const { OrbitControls } = await import('three/examples/jsm/controls/OrbitControls.js')
  controls = new OrbitControls(camera, renderer.domElement)
  controls.enableDamping = true
  controls.dampingFactor = 0.05
  controls.screenSpacePanning = false
  controls.minDistance = 10
  controls.maxDistance = 100
  controls.maxPolarAngle = Math.PI / 2

  // 添加事件监听器
  window.addEventListener('resize', onWindowResize)
  renderer.domElement.addEventListener('dblclick', onDoubleClick)
}

const createWarehouses = () => {
  warehouseConfigs.forEach(config => {
    createWarehouse(config)
  })
}

const createWarehouse = (config) => {
  const { name, position } = config

  // 仓库尺寸
  const width = 10
  const height = 5
  const depth = 25

  // 创建仓库组
  const warehouseGroup = new THREE.Group()
  warehouseGroup.position.set(position.x, height / 2, position.z)
  warehouseGroup.name = name
  warehouseGroup.userData = { isWarehouse: true, name: name }

  // 创建围墙（只创建四面墙，内部是空的）
  createWalls(warehouseGroup, width, height, depth)

  // 创建屋顶
  createRoof(warehouseGroup, width, height, depth)
  // 创建仓库名称标签
  createNameLabel(warehouseGroup, name, width, height, depth)
  scene.add(warehouseGroup)
}

// 创建围墙
const createWalls = (group, width, height, depth) => {
  const wallMaterial = new THREE.MeshStandardMaterial({
    color: 0xFFFFFF,
    roughness: 0.3,
    metalness: 0.0
  })

  // 前墙
  const frontWallGeometry = new THREE.BoxGeometry(width, height, 0.5)
  const frontWall = new THREE.Mesh(frontWallGeometry, wallMaterial)
  frontWall.position.set(0, 0, depth / 2)
  group.add(frontWall)

  // 后墙
  const backWallGeometry = new THREE.BoxGeometry(width, height, 0.5)
  const backWall = new THREE.Mesh(backWallGeometry, wallMaterial)
  backWall.position.set(0, 0, -depth / 2)
  group.add(backWall)

  // 左侧墙
  const leftWallGeometry = new THREE.BoxGeometry(0.5, height, depth)
  const leftWall = new THREE.Mesh(leftWallGeometry, wallMaterial)
  leftWall.position.set(-width / 2, 0, 0)
  group.add(leftWall)

  // 右侧墙
  const rightWallGeometry = new THREE.BoxGeometry(0.5, height, depth)
  const rightWall = new THREE.Mesh(rightWallGeometry, wallMaterial)
  rightWall.position.set(width / 2, 0, 0)
  group.add(rightWall)
}

// 创建屋顶 - 修正版
const createRoof = (group, width, height, depth) => {
  // 屋顶材质 - 蓝色
  const roofMaterial = new THREE.MeshStandardMaterial({
    color: 0x1E90FF,
    roughness: 0.7,
    metalness: 0.3
  })

  // 屋顶尺寸
  const roofThickness = 0.2 // 屋顶薄片厚度
  const roofLength = depth // 屋顶长度与仓库深度一致

  // 计算屋顶斜面长度（根据45度角计算）
  const roofSlopeLength = Math.sqrt(2) * (width / 2)

  // 创建左侧屋顶片
  const leftRoofGeometry = new THREE.BoxGeometry(roofSlopeLength, roofThickness, roofLength)
  const leftRoof = new THREE.Mesh(leftRoofGeometry, roofMaterial)

  // 计算左侧屋顶片的位置和旋转
  const roofHeight = roofSlopeLength / 2 // 屋顶高度
  leftRoof.position.set(-width / 4, height / 2 + roofHeight / 2, 0)
  leftRoof.rotation.z = Math.PI / 4 // 45度角

  group.add(leftRoof)

  // 创建右侧屋顶片
  const rightRoofGeometry = new THREE.BoxGeometry(roofSlopeLength, roofThickness, roofLength)
  const rightRoof = new THREE.Mesh(rightRoofGeometry, roofMaterial)

  // 计算右侧屋顶片的位置和旋转
  rightRoof.position.set(width / 4, height / 2 + roofHeight / 2, 0)
  rightRoof.rotation.z = -Math.PI / 4 // -45度角

  group.add(rightRoof)

  // 添加屋脊
  const ridgeGeometry = new THREE.BoxGeometry(0.3, 0.3, depth + 0.2)
  const ridgeMaterial = new THREE.MeshStandardMaterial({
    color: 0x1C86EE,
    roughness: 0.5,
    metalness: 0.5
  })
  const ridge = new THREE.Mesh(ridgeGeometry, ridgeMaterial)
  ridge.position.set(0, height / 2 + roofHeight, 0)
  group.add(ridge)
}
// 创建名称标签 - 使用Sprite替代3D文字
const createNameLabel = (group, name, width, height, depth) => {
  // 创建canvas来绘制文字
  const canvas = document.createElement('canvas')
  const context = canvas.getContext('2d')
  canvas.width = 256
  canvas.height = 128
  
  // 绘制背景
  context.fillStyle = 'rgba(0, 0, 0, 0.7)'
  context.fillRect(0, 0, canvas.width, canvas.height)
  
  // 绘制文字
  context.font = 'bold 40px Arial'
  context.fillStyle = 'white'
  context.textAlign = 'center'
  context.textBaseline = 'middle'
  context.fillText(name, canvas.width / 2, canvas.height / 2)
  
  // 创建纹理
  const texture = new THREE.CanvasTexture(canvas)
  
  // 创建Sprite材质
  const spriteMaterial = new THREE.SpriteMaterial({
    map: texture,
    transparent: true
  })
  
  // 创建Sprite
  const sprite = new THREE.Sprite(spriteMaterial)
  
  // 计算屋顶高度
  const roofSlopeLength = Math.sqrt(2) * (width / 2)
  const roofHeight = roofSlopeLength / 2
  
  // 设置Sprite位置（在屋顶上方）
  sprite.position.set(0, height/2 + roofHeight + 3, 0)
  sprite.scale.set(8, 4, 1) // 调整Sprite大小
  
  // 将Sprite添加到仓库组
  group.add(sprite)
}
const onWindowResize = () => {
  camera.aspect = container.value.clientWidth / container.value.clientHeight
  camera.updateProjectionMatrix()
  renderer.setSize(container.value.clientWidth, container.value.clientHeight)
}

const onDoubleClick = (event) => {
  // 计算鼠标位置
  const rect = renderer.domElement.getBoundingClientRect()
  mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1
  mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1

  // 发射射线
  raycaster.setFromCamera(mouse, camera)
  const intersects = raycaster.intersectObjects(scene.children, true)

  // 检查是否点击了仓库
  for (let i = 0; i < intersects.length; i++) {
    let object = intersects[i].object
    // 向上遍历父级，查找仓库对象
    while (object !== null && object !== scene) {
      if (object.userData && object.userData.isWarehouse) {
        emit('warehouse-selected')
        return
      }
      object = object.parent
    }
  }
}

const animate = () => {
  requestAnimationFrame(animate)

  // 更新控制器
  if (controls) {
    controls.update()
  }

  renderer.render(scene, camera)
}
</script>

<style scoped>
.warehouse-scene {
  width: 100%;
  height: 100%;
  position: relative;
}

.controls-info {
  position: absolute;
  bottom: 20px;
  left: 20px;
  background: rgba(0, 0, 0, 0.5);
  padding: 15px;
  border-radius: 5px;
  font-size: 0.9rem;
}

.controls-info p {
  margin: 5px 0;
}
</style>